import Client, {
    CreateStackRequest,
    CreateStackResponse,
    ListStacksRequest,
    ListStacksResponse,
    UpdateStackRequest,
    UpdateStackResponse,
    ValidateTemplateRequest,
    ValidateTemplateResponse

} from '@alicloud/ros20190910'
import process from 'process'
import OpenApi, * as $OpenApi from '@alicloud/openapi-client';
import * as step from '@flow-step/step-toolkit'
import {getParams} from './params'



export interface RosInterface{
    createStack(request: CreateStackRequest): Promise<CreateStackResponse>
    listStacks(request: ListStacksRequest): Promise<ListStacksResponse>
    updateStack(request: UpdateStackRequest): Promise<UpdateStackResponse>
    validateTemplate(request: ValidateTemplateRequest): Promise<ValidateTemplateResponse>
}


export class Ros implements RosInterface{
    private readonly client: Client

    constructor(client: Client) {
        this.client = client
    }

    async createStack(request: CreateStackRequest): Promise<CreateStackResponse> {
        return this.client.createStack(request)
    }

    async listStacks(request: ListStacksRequest): Promise<ListStacksResponse> {
        return this.client.listStacks(request)
    }

    async updateStack(request: UpdateStackRequest): Promise<UpdateStackResponse> {
        return this.client.updateStack(request)
    }

    async validateTemplate(request: ValidateTemplateRequest): Promise<ValidateTemplateResponse> {
        return this.client.validateTemplate(request)
    }

}


export async function getROSClient() {
    if (process.env.ROS_ACCESS_KEY_ID == undefined){
        step.info(`Getting ROS Certificate`)
        const certificate = await getROSCertificate()
        step.exportEnvVar("ROS_ACCESS_KEY_ID", certificate.accessKeyId)
        step.exportEnvVar("ROS_ACCESS_KEY_SECRET", certificate.accessKeySecret)
        step.exportEnvVar("ROS_SECURITY_TOKEN", certificate.securityToken)
    }

    step.addOutput(`ROS_ACCESS_KEY_ID=${process.env.ROS_ACCESS_KEY_ID}`)
    step.addOutput(`ROS_ACCESS_KEY_SECRET=${process.env.ROS_ACCESS_KEY_SECRET}`)
    step.addOutput(`ROS_SECURITY_TOKEN=${process.env.ROS_SECURITY_TOKEN}`)

    let config = new $OpenApi.Config({
        accessKeyId: process.env.ROS_ACCESS_KEY_ID,
        accessKeySecret: process.env.ROS_ACCESS_KEY_SECRET,
        securityToken: process.env.ROS_SECURITY_TOKEN,
        readTimeout: 120000,
        connectTimeout: 120000
    });
    const params = getParams()
    if (params.ROS_DEPLOYMENT_LOCATION == 'intl') {
        config.endpoint = `ros-intl.aliyuncs.com`;
    } else {
        config.endpoint = `ros.aliyuncs.com`;
    }
    return Promise.resolve(new Client(config));
}

export async function getROSCertificate(){
    const flowJobToken: string | undefined =
        process.env['FLOW_JOB_TOKEN']
    if (flowJobToken == undefined) {
        throw new Error('Missing FLOW_JOB_TOKEN')
    }
    const certificate = await step.certificate.getRamStsCertificate(flowJobToken,process.env.SERVICE_CONNECTION_ID as string)

    if (certificate === undefined || certificate.accessKeyId === "") {
        throw new Error(`Get RamStsCertificate but error: ${JSON.stringify(certificate)}`)
    }
    step.debug(`Get RamStsCertificate data: ${JSON.stringify(certificate)}`)

    return Promise.resolve(certificate)
}